Docker 中 Nginx 网络配置

Docker 中 Nginx 网络配置完全指南

在使用 Docker 部署 Nginx 时,网络几乎是最容易出问题、也最容易被误解的一层。本文将系统性讲解:

如果你曾遇到:

这篇文章就是为你写的。


一、最重要的心智模型(一切问题的根源)

Nginx 运行在容器里,它看到的网络世界,只属于这个容器。

也就是说:

而是:

[ nginx 容器 ] 的网络命名空间

这条规则一旦记住,80% 的 Docker + Nginx 问题都会自动消失。


二、Docker 网络的三种常见场景

场景 A:Nginx 反代 同一个 docker-compose 中的其他容器

网络结构

graph LR

N[Nginx 容器] -->|HTTP| A[App 容器]

Docker Compose 默认会:

正确配置方式

docker-compose.yml

services:
nginx:
	image: nginx
app:
	image: my-app
expose:
- "8080"

nginx.conf

proxy_pass http://app:8080;

关键点

这是生产环境最推荐的方式


场景 B:Nginx 访问 宿主机上的服务

这是最经典的翻车点。

网络结构

graph TD

N[Nginx 容器]

H[宿主机]

S[宿主机服务 :8080]

  

N -->|host.docker.internal| H

H --> S

为什么 127.0.0.1 一定是错的?

proxy_pass http://127.0.0.1:8080; # ❌

因为:


正确三步走(Linux)

1️⃣ 宿主机服务必须监听在 0.0.0.0
server --host 0.0.0.0 --port 8080

验证:

ss -lntp | grep 8080
# 应看到 0.0.0.0:8080

2️⃣ docker-compose 添加 host 映射
extra_hosts:
- "host.docker.internal:host-gateway"

3️⃣ Nginx 使用 host.docker.internal
proxy_pass http://host.docker.internal:8080;

场景 C:Nginx 访问 其他 docker-compose / 独立容器

网络结构

graph LR

N[Nginx] -->|shared network| API[API 容器]

解决方案:共享 Docker Network

docker network create shared-net
services:
nginx:
	networks: [shared-net]
api:
	networks: [shared-net]
networks:
	shared-net:
		external: true
proxy_pass http://api:9000;

三、地址选择速查表(实战必备)

目标服务 proxy_pass 写法
同 compose 容器 http://service_name:port
宿主机服务 http://host.docker.internal:port
其他 compose http://container_name:port
nginx 自己 http://127.0.0.1:port
外网服务 http://domain:port

四、WebSocket / RPC 场景的标准模板

map $http_upgrade $connection_upgrade {
	default upgrade;
	'' close;
}

server {
	listen 80;
	location / {
		proxy_pass http://host.docker.internal:8080;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $connection_upgrade;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

五、排错三板斧(永远先做这三步)

1️⃣ 进入 Nginx 容器

docker exec -it nginx sh

2️⃣ 在容器内直接 curl upstream

curl http://app:8080
curl http://host.docker.internal:8080

curl 不通,nginx 一定不通


3️⃣ 看 error.log 对应含义

错误信息 含义
connect() failed (111) 地址 / 监听问题
no route to host network 未加入
upstream prematurely closed 协议 / header

六、总结(一句话版本)

Docker 中配置 Nginx,不是在写配置文件,而是在选“网络视角”。

只要你始终记住:

Docker + Nginx 就会变得非常可控、非常稳定。